package com.sun.showcase.conf.security;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Service;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.StringUtils;

import com.sun.showcase.biz.basic.dao.ResourceInfoDao;
import com.sun.showcase.client.domain.basic.ResourceInfo;
import com.sun.showcase.client.query.basic.ResourceInfoQuery;
import com.sun.showcase.utils.StringConstant;


/**
 * 获取所有资源对应角色的定义
 */
@Service
public class InvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource,InitializingBean{

	
	private AntPathMatcher urlUtils = new AntPathMatcher();
	
	
	private static Map<String, Collection<ConfigAttribute>> resources = null;
	
	
	@Resource
	private ResourceInfoDao resourceInfoDao;

	
	/**
	 * 检索系统中所有资源
	 * 资源为key,角色为value
	 * 资源通常为url
	 * 一个资源对应多个角色来访问
	 */
	public void loadResourceDefine(){
		
		//检索系统资源
		ResourceInfoQuery query = new ResourceInfoQuery();
		query.setType(StringConstant.ZERO);
		List<ResourceInfo> list = resourceInfoDao.findList(query);
		
		resources = new HashMap<String, Collection<ConfigAttribute>>();

		for(ResourceInfo resource : list){
			
	
			String url = resource.getUrl();//路径
			
			String id = String.valueOf(resource.getId());//资源Id
			
			if(StringUtils.isEmpty(id))
				continue;
			
			ConfigAttribute attribute = new SecurityConfig(id);
			
			if(resources.containsKey(url)){
				
				Collection<ConfigAttribute> roleIds = resources.get(url);
				
				roleIds.add(attribute);
				
				resources.put(url, roleIds);
				
			}else{
				
				Collection<ConfigAttribute> attributes = new ArrayList<ConfigAttribute>();
				
				attributes.add(attribute);
				
				resources.put(url, attributes);
				
			}
			
		}

	}
	
	
	/**
	 * 根据url,找到相关角色配置
	 */
	public Collection<ConfigAttribute> getAttributes(Object object)throws IllegalArgumentException {
		
		String url = ((FilterInvocation) object).getRequestUrl();
		
		int firstQuestionMarkIndex = url.indexOf("?");
		
		if (firstQuestionMarkIndex != -1) {  
            url = url.substring(0, firstQuestionMarkIndex);  
        } 
		
		Iterator<String> ite = resources.keySet().iterator();  

	    while(ite.hasNext()){
	    	
	    	String tmpURL = ite.next();  

	    	if(urlUtils.matchStart(tmpURL,url)){
	    		return resources.get(tmpURL);  
	    	}
	    	  
	    }
	    
		return null;
	}
	
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		
		return null;
	}

	public boolean supports(Class<?> clazz) {
		
		return true;
	}


	@Override
	public void afterPropertiesSet() throws Exception {
		
		loadResourceDefine();
		
	}

}
